package com.karolak.sm.state;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.karolak.sm.StateMachine;
import com.karolak.sm.event.Event;
import com.karolak.sm.exception.TransitionException;

public class StateBase {

	protected Log log = LogFactory.getLog(getClass());
	private StateId stateId;
	private StateMachine stateMachine;

	public StateBase(StateMachine stateMachine, StateId stateId) {
		this.stateId = stateId;
		this.stateMachine = stateMachine;
	}

	// === transition api ===//
	public void execute(Event event) throws TransitionException {
		Transition transition = getStateMachine().getTransition(event);

		if (transition == null) {
			String msg = String.format("Unsupported transition  event:%s, state:%s.", event, getStateId());
			throw new TransitionException(msg);
		}

		StateId targetStateId = transition.getTargetStateId();
		if (getStateId() != transition.getStateId() || targetStateId != transition.getTargetStateId()) {
			String msg = String.format("Unsupported transition for event:%s, state:%s , existing transition:%s.", transition.getEvent(), getStateId(), transition);
			throw new TransitionException(msg);
		}

		// execute bl
		log.info(String.format("Executing transition:%s.", transition));
		getStateMachine().update(transition.getEvent());
	}

	// == get/set ===//
	public StateId getStateId() {
		return stateId;
	}

	protected StateMachine getStateMachine() {
		return stateMachine;
	}
}
